package com.earthchen.core.support.quartz.job;

import com.earthchen.core.support.distributedlock.redis.RedissLockUtil;
import com.earthchen.core.support.generator.Sequence;
import com.earthchen.core.support.quartz.domain.TaskScheduled;
import com.earthchen.core.util.SpringUtils;
import org.quartz.Job;
import org.quartz.JobDataMap;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.redisson.api.RLock;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * @author earthchen
 * @date 2018/8/31
 **/
public class BaseJob implements Job {

    private final Logger logger = LoggerFactory.getLogger(BaseJob.class);

    @Override
    public void execute(JobExecutionContext context) throws JobExecutionException {
        long start = System.currentTimeMillis();
        JobDataMap jobDataMap = context.getJobDetail().getJobDataMap();
        String taskType = jobDataMap.getString("taskType");
        String targetObject = jobDataMap.getString("targetObject");
        String targetMethod = jobDataMap.getString("targetMethod");
        String requestId = Sequence.next().toString();
        String key = targetMethod + "." + targetObject + ":" + requestId;
        try {
            logger.info("定时任务[{}.{}]开始", targetObject, targetMethod);

            RLock rLock = RedissLockUtil.lock(key, 60 * 60 * 5);
            if (rLock.tryLock()) {
                try {
                    if (TaskScheduled.TaskType.local.equals(taskType)) {
                        Object refer = SpringUtils.getBean(targetObject);
                        refer.getClass().getDeclaredMethod(targetMethod).invoke(refer);

                    } else {
                        Object refer = SpringUtils.getBean(targetObject);
                        refer.getClass().getDeclaredMethod(targetMethod).invoke(refer);
                    }
                    double time = (System.currentTimeMillis() - start) / 1000.0;
                    logger.info("定时任务[{}.{}]用时：{}s", targetObject, targetMethod, Double.toString(time));
                } finally {
                    rLock.unlock();
                }
            }
        } catch (Exception e) {
            throw new JobExecutionException(e);
        }
    }
}
